package com.watson.todolist.testing;

import java.util.ArrayList;
import java.util.List;

import com.watson.todolist.todoListActivity;
import com.watson.todolist.constants.DatabaseConstants;
import com.watson.todolist.database.AccountManager;
import com.watson.todolist.database.DatabaseManager;
import com.watson.todolist.database.ToDoListManager;
import com.watson.todolist.to.TodoItem;
import com.watson.todolist.to.TodoListAccount;

import junit.framework.Assert;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.test.AndroidTestCase;
import android.util.Log;

/**
 * This class contains the tests for Laurens four chosen methods (getAllTodoListItemsByUserId, 
 * getAllMatchesWithCompletedCriteriaIncluded, testGetLastDateByUserId, testGetFirstDateByUserId) for the M9 and M10 milestone. Both methods are
 *  in the ToDoListManager class.
 * 
 * @author Lauren Tanguay
 * 
 * @since 1.0
 */
public class LaurenTest1 extends AndroidTestCase {

	/**
	 * This test method is responsible for testing the method getAllTodoListItemsByUserId
	 * in the TodoListManager class. It utilizes black box testing methods by seting up
	 * three user accounts and assigning each a certain number of TodoItems with known
	 * names. The method checks that the corresponding Lists from each userId have the
	 * correct number of items, and that the items are named appropriately. It also utilizes
	 * white box testing methods by ensuring every line of code in the method is implemented.
	 * 
	 * @throws Throwable
	 */
    public void testGetAllTodoListItemsByUserId() throws Throwable {
       
    	DatabaseManager dbManager = new DatabaseManager();
		SQLiteDatabase db = dbManager.open(getContext());
		ToDoListManager todoListManager = new ToDoListManager(db);
		AccountManager accountManager = new AccountManager(db);
    	
		// Create 3 different Accounts for testing purposes
		long userId1 = accountManager.createUserAccount("TestAccount1", 
				"testaccount1@email.com","testaccount1");
		long userId2 = accountManager.createUserAccount("TestAccount2", 
				"testaccount2@email.com","testaccount2");
		long userId3 = accountManager.createUserAccount("TestAccount3", 
				"testaccount3@email.com","testaccount3");
		
		//Create todo items for Test Account 1
		todoListManager.createTodoListItem(userId1, "1a", 0, 0, 0, 0, "", 0, 0, 0);
		todoListManager.createTodoListItem(userId1, "1b", 0, 0, 0, 0, "", 0, 0, 0);
		todoListManager.createTodoListItem(userId1, "1c", 0, 0, 0, 0, "", 0, 0, 0);
		todoListManager.createTodoListItem(userId1, "1d", 0, 0, 0, 0, "", 0, 0, 0);
		
		//Create todo items for Test Account 2
		todoListManager.createTodoListItem(userId2, "2a", 0, 0, 0, 0, "", 0, 0, 0);
		todoListManager.createTodoListItem(userId2, "2b", 0, 0, 0, 0, "", 0, 0, 0);
		
		// getAllTodoListItemsByUserId() for each Account
		List<TodoItem> user1List = todoListManager.getAllTodoListItemsByUserId(userId1);
		List<TodoItem> user2List = todoListManager.getAllTodoListItemsByUserId(userId2);
		List<TodoItem> user3List = todoListManager.getAllTodoListItemsByUserId(userId3);
		
		//check that getAllTodoListItemsByUserId returns 4 items for Account1
		Assert.assertTrue(user1List.size() == 4);
		//check that getAllTodoListItemsByUserId returns 2 items for Account2
		Assert.assertTrue(user2List.size() == 2);
		//check that getAllTodoListItemsByUserId returns 0 items for Account3
		Assert.assertTrue(user3List == null || user3List.size() == 0);
		
		//check that all items in user1List have names staring with 1
		for (TodoItem item: user1List) {
			Assert.assertTrue(item.getTodoItemName().charAt(0) == '1');
		}
		//check that all items in user2List have names staring with 2
		for (TodoItem item: user2List) {
			Assert.assertTrue(item.getTodoItemName().charAt(0) == '2');
		}
		
		//check that improper userId returns null
		List<TodoItem> user4List = todoListManager.getAllTodoListItemsByUserId(100000);
		Assert.assertTrue(user4List == null);
		
		dbManager.close();
    }
    
    /**
	 * This test method is responsible for testing the method 
	 * getAllMatchesWithCompletedCriteriaIncluded in the TodoListManager class. 
	 * It utilizes black box testing methods by seting up todo items for a user
	 * account and checking that it correctly filters the known values. It also
	 * utilizes white box testing but ensuring every line of code in the method is
	 * used.
	 * 
	 * @throws Throwable
	 */
    public void testGetAllMatchesWithCompletedCriteriaIncluded() throws Throwable {
       
    	DatabaseManager dbManager = new DatabaseManager();
		SQLiteDatabase db = dbManager.open(getContext());
		ToDoListManager todoListManager = new ToDoListManager(db);
		AccountManager accountManager = new AccountManager(db);
    	
		// Create 3 different Accounts for testing purposes
		long userId1 = accountManager.createUserAccount("TestAccount1", 
				"testaccount1@email.com","testaccount1");
		
		//Create todo items for Test Account 1 - alternating in completeness, categories
		//naming convention - i/c for incomplete/complete, # for Account#, letter for category
		todoListManager.createTodoListItem(userId1, "i_1n", 0, 450, 0, 0, "", 0, 0, 0);
		todoListManager.createTodoListItem(userId1, "i_1n1", 0, 3, 0, 0, "", 0, 0, 0);
		todoListManager.createTodoListItem(userId1, "c_1h", 1, 400, 0, 0, "", 0, 0, 1);
		todoListManager.createTodoListItem(userId1, "i_1w1", 2, 100, 0, 0, "", 0, 0, 0);
		todoListManager.createTodoListItem(userId1, "c_1w2", 2, 5000, 0, 0, "", 0, 0, 1);
		todoListManager.createTodoListItem(userId1, "i_1w3", 2, 10, 0, 0, "", 0, 0, 0);
		todoListManager.createTodoListItem(userId1, "i_1p1", 3, 36, 0, 0, "", 0, 0, 0);
		todoListManager.createTodoListItem(userId1, "i_1p2", 3, 67, 0, 0, "", 0, 0, 0);
		
		// user1, all categories, incomplete only, all times
		Cursor cursor = todoListManager.getAllMatchesWithCompletedCriteriaIncluded(userId1,0, 0, 0);
		List<TodoItem> todoItemList = new ArrayList<TodoItem>();
		for(cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
			TodoItem todoItem = new TodoItem();
			todoItem.setDescription(cursor.getString(cursor
					.getColumnIndex(DatabaseConstants.TODO_ITEM_TABLE_DESCRIPTION)));
			todoItem.setLatitude(cursor.getFloat(cursor
					.getColumnIndex(DatabaseConstants.TODO_ITEM_TABLE_LOCATION_LATITUDE)));
			todoItem.setLongitude(cursor.getFloat(cursor
					.getColumnIndex(DatabaseConstants.TODO_ITEM_TABLE_LOCATION_LONGITUDE)));
			todoItem.setAlarmRecurrenceType(cursor.getInt(cursor
					.getColumnIndex(DatabaseConstants.TODO_ITEM_TABLE_TODO_ALARM_RECURRENCE_TYPE)));
			todoItem.setPriorAlarmReminderTime(cursor.getLong(cursor
					.getColumnIndex(DatabaseConstants.TODO_ITEM_TABLE_TODO_PRIOR_ALARM_REMINDER_TIME)));
			todoItem.setTodoCompleted(cursor.getInt(cursor
					.getColumnIndex(DatabaseConstants.TODO_ITEM_TABLE_TODO_COMPLETED)));
			todoItem.setTodoItemCategoryCode(cursor.getInt(cursor
					.getColumnIndex(DatabaseConstants.TODO_ITEM_TABLE_CATEGORY_CODE)));
			todoItem.setTodoItemId(cursor.getLong(cursor
					.getColumnIndex(DatabaseConstants.ID)));
			todoItem.setTodoItemName(cursor.getString(cursor
					.getColumnIndex(DatabaseConstants.TODO_ITEM_TABLE_TODO_ITEM_NAME)));
			todoItem.setTodoTime(cursor.getLong(cursor
					.getColumnIndex(DatabaseConstants.TODO_ITEM_TABLE_TODO_TIME)));
			todoItem.setUserId(cursor.getLong(cursor
					.getColumnIndex(DatabaseConstants.TODO_ITEM_TABLE_USER_ID)));
			todoItemList.add(todoItem);
		}
		Assert.assertTrue(todoItemList.size() == 6);
		for (TodoItem item: todoItemList) {
			Assert.assertTrue(item.getTodoItemName().charAt(0) == 'i');
		}
		
		// user1, all categories, incomplete only, times after 30
				cursor = todoListManager.getAllMatchesWithCompletedCriteriaIncluded(userId1,0, 0, 30);
				todoItemList = new ArrayList<TodoItem>();
				for(cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
					TodoItem todoItem = new TodoItem();
					todoItem.setDescription(cursor.getString(cursor
							.getColumnIndex(DatabaseConstants.TODO_ITEM_TABLE_DESCRIPTION)));
					todoItem.setLatitude(cursor.getFloat(cursor
							.getColumnIndex(DatabaseConstants.TODO_ITEM_TABLE_LOCATION_LATITUDE)));
					todoItem.setLongitude(cursor.getFloat(cursor
							.getColumnIndex(DatabaseConstants.TODO_ITEM_TABLE_LOCATION_LONGITUDE)));
					todoItem.setAlarmRecurrenceType(cursor.getInt(cursor
							.getColumnIndex(DatabaseConstants.TODO_ITEM_TABLE_TODO_ALARM_RECURRENCE_TYPE)));
					todoItem.setPriorAlarmReminderTime(cursor.getLong(cursor
							.getColumnIndex(DatabaseConstants.TODO_ITEM_TABLE_TODO_PRIOR_ALARM_REMINDER_TIME)));
					todoItem.setTodoCompleted(cursor.getInt(cursor
							.getColumnIndex(DatabaseConstants.TODO_ITEM_TABLE_TODO_COMPLETED)));
					todoItem.setTodoItemCategoryCode(cursor.getInt(cursor
							.getColumnIndex(DatabaseConstants.TODO_ITEM_TABLE_CATEGORY_CODE)));
					todoItem.setTodoItemId(cursor.getLong(cursor
							.getColumnIndex(DatabaseConstants.ID)));
					todoItem.setTodoItemName(cursor.getString(cursor
							.getColumnIndex(DatabaseConstants.TODO_ITEM_TABLE_TODO_ITEM_NAME)));
					todoItem.setTodoTime(cursor.getLong(cursor
							.getColumnIndex(DatabaseConstants.TODO_ITEM_TABLE_TODO_TIME)));
					todoItem.setUserId(cursor.getLong(cursor
							.getColumnIndex(DatabaseConstants.TODO_ITEM_TABLE_USER_ID)));
					todoItemList.add(todoItem);
				}
				Assert.assertTrue(todoItemList.size() == 4);
				for (TodoItem item: todoItemList) {
					Assert.assertTrue(item.getTodoItemName().charAt(0) == 'i');
				}
		
				// user1, work only, incomplete only, times after 80
				cursor = todoListManager.getAllMatchesWithCompletedCriteriaIncluded(userId1,0, 2, 80);
				todoItemList = new ArrayList<TodoItem>();
				for(cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
					TodoItem todoItem = new TodoItem();
					todoItem.setDescription(cursor.getString(cursor
							.getColumnIndex(DatabaseConstants.TODO_ITEM_TABLE_DESCRIPTION)));
					todoItem.setLatitude(cursor.getFloat(cursor
							.getColumnIndex(DatabaseConstants.TODO_ITEM_TABLE_LOCATION_LATITUDE)));
					todoItem.setLongitude(cursor.getFloat(cursor
							.getColumnIndex(DatabaseConstants.TODO_ITEM_TABLE_LOCATION_LONGITUDE)));
					todoItem.setAlarmRecurrenceType(cursor.getInt(cursor
							.getColumnIndex(DatabaseConstants.TODO_ITEM_TABLE_TODO_ALARM_RECURRENCE_TYPE)));
					todoItem.setPriorAlarmReminderTime(cursor.getLong(cursor
							.getColumnIndex(DatabaseConstants.TODO_ITEM_TABLE_TODO_PRIOR_ALARM_REMINDER_TIME)));
					todoItem.setTodoCompleted(cursor.getInt(cursor
							.getColumnIndex(DatabaseConstants.TODO_ITEM_TABLE_TODO_COMPLETED)));
					todoItem.setTodoItemCategoryCode(cursor.getInt(cursor
							.getColumnIndex(DatabaseConstants.TODO_ITEM_TABLE_CATEGORY_CODE)));
					todoItem.setTodoItemId(cursor.getLong(cursor
							.getColumnIndex(DatabaseConstants.ID)));
					todoItem.setTodoItemName(cursor.getString(cursor
							.getColumnIndex(DatabaseConstants.TODO_ITEM_TABLE_TODO_ITEM_NAME)));
					todoItem.setTodoTime(cursor.getLong(cursor
							.getColumnIndex(DatabaseConstants.TODO_ITEM_TABLE_TODO_TIME)));
					todoItem.setUserId(cursor.getLong(cursor
							.getColumnIndex(DatabaseConstants.TODO_ITEM_TABLE_USER_ID)));
					todoItemList.add(todoItem);
				}
				Assert.assertTrue(todoItemList.size() == 1);
				for (TodoItem item: todoItemList) {
					Assert.assertTrue(item.getTodoItemName().charAt(0) == 'i');
					Assert.assertTrue(item.getTodoItemName().charAt(3) == 'w');
				}
				
				// user1, personal only, complete only, times after 0 (NO MATCHES)
				cursor = todoListManager.getAllMatchesWithCompletedCriteriaIncluded(userId1,1, 3, 0);
				Assert.assertTrue(cursor == null);
		dbManager.close();
    }
    
    /**
	 * This test method is responsible for testing the method getLastDateByUserId
	 * in the todoListManager class.It utilizes blackbox testing by testing
	 * for each type of valid input and white box testing by ensuring each line of
	 * the code is executed.
	 * 
	 * @throws Throwable
	 */
    public void testGetLastDateByUserId() throws Throwable {
       
    	DatabaseManager dbManager = new DatabaseManager();
		SQLiteDatabase db = dbManager.open(getContext());
		ToDoListManager todoListManager = new ToDoListManager(db);
		AccountManager accountManager = new AccountManager(db);
    	
		// Create Account for testing purposes
		long userId1 = accountManager.createUserAccount("TestAccount1", 
				"testaccount1@email.com","testaccount1");
		
		//Create todo items for Test Account 1
		todoListManager.createTodoListItem(userId1, "1a", 0, 0, 0, 0, "", 0, 0, 0);
		todoListManager.createTodoListItem(userId1, "1b", 0, 10, 0, 0, "", 0, 0, 0);
		todoListManager.createTodoListItem(userId1, "1c", 0, 200, 0, 0, "", 0, 0, 0);
		todoListManager.createTodoListItem(userId1, "1d", 0, 55555, 0, 0, "", 0, 0, 0);
		todoListManager.createTodoListItem(userId1, "1e", 0, 4444, 0, 0, "", 0, 0, 0);
		todoListManager.createTodoListItem(userId1, "1f", 0, 333, 0, 0, "", 0, 0, 0);
		todoListManager.createTodoListItem(userId1, "1g", 0, 22, 0, 0, "", 0, 0, 0);
		todoListManager.createTodoListItem(userId1, "1h", 0, 1, 0, 0, "", 0, 0, 0);
		todoListManager.createTodoListItem(userId1, "1i", 0, 0, 0, 0, "", 0, 0, 0);
		todoListManager.createTodoListItem(userId1, "1j", 0, 57, 0, 0, "", 0, 0, 0);
		
		Assert.assertTrue(todoListManager.getLastDateByUserId(userId1) == 55555);
		
		todoListManager.createTodoListItem(userId1, "1k", 0, 666666, 0, 0, "", 0, 0, 0);
		Assert.assertTrue(todoListManager.getLastDateByUserId(userId1) == 666666);
		
		todoListManager.createTodoListItem(userId1, "1k", 0, 766666, 0, 0, "", 0, 0, 0);
		Assert.assertTrue(todoListManager.getLastDateByUserId(userId1) == 766666);
		
		// Create Account for testing purposes with no todo items
		long userId2 = accountManager.createUserAccount("TestAccount2", 
						"testaccount2@email.com","testaccount2");
				
		Assert.assertTrue(todoListManager.getLastDateByUserId(userId2) == 0);
		
		// Create Account for testing purposes with one todo item
		long userId3 = accountManager.createUserAccount("TestAccount3", 
						"testaccount3@email.com","testaccount3");
		todoListManager.createTodoListItem(userId3, "3a", 0, 20, 0, 0, "", 0, 0, 0);	
		Assert.assertTrue(todoListManager.getLastDateByUserId(userId3) == 20);
		
		dbManager.close();
    }
    
    /**
	 * This test method is responsible for testing the method getLastDateByUserId
	 * in the todoListManager class.It utilizes blackbox testing by testing
	 * for each type of valid input and white box testing by ensuring each line of
	 * the code is executed.
	 * 
	 * @throws Throwable
	 */
    public void testGetFirstDateByUserId() throws Throwable {
       
    	DatabaseManager dbManager = new DatabaseManager();
		SQLiteDatabase db = dbManager.open(getContext());
		ToDoListManager todoListManager = new ToDoListManager(db);
		AccountManager accountManager = new AccountManager(db);
    	
		// Create Account for testing purposes
		long userId4 = accountManager.createUserAccount("TestAccount4", 
				"testaccount4@email.com","testaccount4");
		
		//Create todo items for Test Account 1
		todoListManager.createTodoListItem(userId4, "1a", 0, 300, 0, 0, "", 0, 0, 0);
		todoListManager.createTodoListItem(userId4, "1b", 0, 200, 0, 0, "", 0, 0, 0);
		todoListManager.createTodoListItem(userId4, "1c", 0, 250, 0, 0, "", 0, 0, 0);
		todoListManager.createTodoListItem(userId4, "1d", 0, 250, 0, 0, "", 0, 0, 0);
		todoListManager.createTodoListItem(userId4, "1e", 0, 250, 0, 0, "", 0, 0, 0);
		todoListManager.createTodoListItem(userId4, "1f", 0, 100, 0, 0, "", 0, 0, 0);
		todoListManager.createTodoListItem(userId4, "1g", 0, 340, 0, 0, "", 0, 0, 0);
		todoListManager.createTodoListItem(userId4, "1h", 1, 341, 0, 0, "", 0, 0, 0);
		todoListManager.createTodoListItem(userId4, "1i", 2, 548, 0, 0, "", 0, 0, 0);
		todoListManager.createTodoListItem(userId4, "1j", 0, 210, 0, 0, "", 0, 0, 0);
		
		Assert.assertTrue(todoListManager.getFirstDateByUserId(userId4) == 100);
		
		todoListManager.createTodoListItem(userId4, "1k", 0, 99, 0, 0, "", 0, 0, 0);
		Assert.assertTrue(todoListManager.getFirstDateByUserId(userId4) == 99);
		
		todoListManager.createTodoListItem(userId4, "1k", 0, 50, 0, 0, "", 0, 0, 0);
		Assert.assertTrue(todoListManager.getFirstDateByUserId(userId4) == 50);
		
		// Create Account for testing purposes with no todo items
		long userId5 = accountManager.createUserAccount("TestAccount5", 
						"testaccount5@email.com","testaccount5");
				
		Assert.assertTrue(todoListManager.getFirstDateByUserId(userId5) == 0);
		
		// Create Account for testing purposes with one todo item
		long userId6 = accountManager.createUserAccount("TestAccount6", 
						"testaccount6@email.com","testaccount6");
		todoListManager.createTodoListItem(userId6, "3a", 0, 20, 0, 0, "", 0, 0, 0);	
		Assert.assertTrue(todoListManager.getFirstDateByUserId(userId6) == 20);
		
		dbManager.close();
    }

}
